iT邦幫忙

2026 iThome 鐵人賽

DAY 25
0
IT Operation

Docker 新手村:從容器到 PostgreSQL 的實戰之路系列 第 26 篇

Day 25 - Docker Network 實戰:讓 Node.js 與 PostgreSQL 互相溝通

  • 分享至 

  • xImage
  •  

學習目標

  • 複習 Docker Network 的用途
  • 了解 Container 之間如何互相連線
  • 將 Node.js 加入 Docker Compose
  • 使用 Service Name 連線 PostgreSQL
  • 了解 localhost 在 Container 中代表什麼

從 localhost 到 Container 連線

Day 24 已經成功讓 Node.js 連線 PostgreSQL。

當時 Node.js 是直接執行在自己的電腦上,所以資料庫設定使用:

host: "localhost"

整個架構是:

Node.js(我的電腦)
       │
       ↓
localhost:5432
       │
       ↓
PostgreSQL Container

但如果今天把 Node.js 也放進 Docker,就不能再直接使用 localhost 連線 PostgreSQL。

這時候就需要再次用到 Day 9 學過的 Docker Network。


為什麼不能使用 localhost?

假設現在有兩個 Container:

Node.js Container

PostgreSQL Container

在 Node.js Container 裡:

localhost

代表的是 Node.js Container 自己。

所以如果 Node.js 使用:

host: "localhost"

它會在自己的 Container 裡尋找 PostgreSQL,當然就會連線失敗。

正確的方式是透過 Docker Network,使用 PostgreSQL 的 Service Name:

host: "postgres"

建立 Node.js 的 Dockerfile

首先在 Node.js 專案中建立:

Dockerfile

內容如下:

FROM node:20

WORKDIR /app

COPY package*.json ./

RUN npm install

COPY . .

CMD ["node", "app.js"]

這和前面 Day 11、Day 12 學過的 Dockerfile 概念相同。

Docker 會根據這份 Dockerfile 建立 Node.js Image。


修改 Node.js 資料庫設定

接著把 Day 24 的:

host: "localhost"

修改成:

host: "postgres"

完整設定:

const client = new Client({
  host: "postgres",
  port: 5432,
  user: "myuser",
  password: "123456",
  database: "schedule_db"
});

這裡的 postgres 就是 compose.yml 中設定的 Service Name。


將 Node.js 加入 compose.yml

接著修改 Compose:

services:
  postgres:
    image: postgres:17
    container_name: my-postgres
    environment:
      POSTGRES_USER: myuser
      POSTGRES_PASSWORD: 123456
      POSTGRES_DB: schedule_db
    ports:
      - "5432:5432"
    volumes:
      - postgres-data:/var/lib/postgresql/data

  app:
    build: .
    container_name: my-node-app
    depends_on:
      - postgres

volumes:
  postgres-data:

現在 Compose 中有兩個服務:

services
│
├── postgres
│
└── app

其中:

build: .

代表使用目前資料夾中的 Dockerfile 建立 Node.js Image。


Docker Compose 自動建立 Network

使用 Docker Compose 時,同一個 Compose 專案中的服務預設會加入同一個 Network。

所以不需要另外手動輸入:

docker network create

Node.js 可以直接透過:

postgres

找到 PostgreSQL。

架構變成:

Docker Network
│
├── app
│    │
│    └───────┐
│            ↓
└────── postgres:5432

這就是 Service Name 很重要的地方。


啟動服務

完成設定後執行:

docker compose up -d --build

其中:

up       → 建立並啟動服務
-d       → 背景執行
--build  → 重新建立需要的 Image

接著查看:

docker compose ps

確認 PostgreSQL 與 Node.js Container 的狀態。


查看 Node.js 執行結果

因為 Node.js 程式會查詢 PostgreSQL,可以使用:

docker compose logs app

如果成功,就可能看到:

PostgreSQL 連線成功!

[
  {
    id: 1,
    name: '小明',
    position: '正職'
  }
]

這代表 Node.js Container 已經成功透過 Docker Network 找到 PostgreSQL Container。


今天的完整架構

現在已經不再是只有一個 Container。

而是:

Docker Compose
      │
      ↓
Docker Network
      │
      ├── Node.js Container
      │        │
      │        │ postgres:5432
      │        ↓
      └── PostgreSQL Container
                   │
                   ↓
              postgres-data
                  Volume

這樣 Node.js 和 PostgreSQL 都可以放在 Docker 中運作。


depends_on 要注意什麼?

Compose 中使用:

depends_on:
  - postgres

代表啟動時會先處理 PostgreSQL 的依賴關係。

但這不代表 PostgreSQL 一定已經完成初始化並準備接受連線。

如果 Node.js 一啟動就立刻連線,有時仍可能因 PostgreSQL 尚未準備完成而失敗。

之後正式開發時,可以加入 Health Check 或重試機制,讓服務之間的啟動更加穩定。


常見錯誤與修正

  • ❌ Node.js Container 使用 localhost → ✅ 改成 PostgreSQL Service Name postgres
  • ❌ Node.js 找不到 PostgreSQL → ✅ 確認兩個服務是否在同一個 Compose 專案
  • ❌ 修改程式後沒有更新 → ✅ 使用 docker compose up -d --build
  • ❌ PostgreSQL 尚未準備完成 → ✅ 可以加入 Health Check 或連線重試
  • ❌ Node.js 執行失敗 → ✅ 使用 docker compose logs app 查看錯誤

今日小挑戰(可交付)

  • [ ] 替 Node.js 建立 Dockerfile
  • [ ] 將 Node.js 加入 compose.yml
  • [ ] 將資料庫 Host 從 localhost 改成 postgres
  • [ ] 使用 docker compose up -d --build
  • [ ] 確認 Node.js 與 PostgreSQL Container
  • [ ] 使用 Logs 查看 Node.js 執行結果
  • [ ] 成功從 Node.js Container 查詢 PostgreSQL

DAY25 心得

今天把 Node.js 也放進 Docker,並透過 Docker Network 連線 PostgreSQL。之前已經學過 Network,但當時只有單純理解 Container 之間可以互相連線,今天才真正把這個觀念應用在程式和資料庫上。

其中最容易搞混的還是 localhost。Node.js 在自己的電腦執行時可以使用 localhost,但進入 Container 後,localhost 就變成 Node.js Container 自己,因此要改成 PostgreSQL 的 Service Name postgres。

做到這裡,Node.js 和 PostgreSQL 已經可以一起透過 Docker Compose 管理。前面學過的 Dockerfile、Image、Container、Network、Volume 和 Compose 也幾乎全部串在一起了。


上一篇
Day 24 - PostgreSQL + Node.js:讓程式連上資料庫
下一篇
Day 26 - 環境變數與 .env:不要把資料庫密碼寫死在程式裡
系列文
Docker 新手村:從容器到 PostgreSQL 的實戰之路 共 31 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言